package invest.data.getdata;

import invest.data.Data;
import invest.pojo.csv.FinanceHistoryCsv;
import invest.pojo.csv.StockHistoryCsv;
import invest.pojo.datapojo.Finance;
import invest.pojo.datapojo.StockHistory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static invest.utils.CsvUtil.*;
import static invest.utils.DateUtil.getDate;

//public class CompanyFinanceData implements Data<List<FinanceHistoryCsv>>  {
public class CompanyFinanceData implements Data<List<Finance>>  {
    String code="";
    String startTime="";
    String endTime="";
    // String url = "http://quotes.money.163.com/service/zycwzb_002269.html?type=report";
    private final String pre = "http://quotes.money.163.com/service/zycwzb_";
    private final String after = ".html?type=report";

    public CompanyFinanceData(String code) {
        this.code = code;
    }
    @Override
    public List<Finance> getData() throws IOException {
        String url = pre + code +after;
        HttpHeaders headers = new HttpHeaders();
        InputStream inputStream = null;
        try {
            RestTemplate restTemplate = new RestTemplate();
            List list = new ArrayList<>();
            headers.setAccept(list);
            ResponseEntity<byte[]> response = restTemplate.exchange(
                    url,
                    HttpMethod.GET,
                    new HttpEntity<byte[]>(headers),
                    byte[].class);

            byte[] result = response.getBody();
            inputStream = new ByteArrayInputStream(result);
            List<String[]> list1 = readCsvFile(inputStream);
            int counts = list1.get(0).length - 1;
            List<Finance> finances = new ArrayList<>();
            for (int i = 0; i < counts; i++) {
                Finance finance = new Finance();
                finance.setCode(this.code);
                finance.setDate(getDate(list1.get(0)[i+1]));
                if (isNumeric(list1.get(1)[i + 1])) {
                    finance.setBasicEarningsPerShare(new Double(list1.get(1)[i+1]));
                }
                if (isNumeric(list1.get(2)[i+1])) {
                    finance.setNetAssetsPerShare(new Double(list1.get(2)[i+1]));
                }
                if (isNumeric(list1.get(3)[i+1])) {
                    finance.setNetCashFlowFromOperatingActivitiesPerShare(new Double(list1.get(3)[i+1]));
                }
                if (isNumeric(list1.get(4)[i+1])) {
                    finance.setMainBusinessIncome(new Double(list1.get(4)[i+1]));
                }
                if (isNumeric(list1.get(5)[i+1])) {
                    finance.setMainBusinessProfit(new Double(list1.get(5)[i+1]));
                }
                if (isNumeric(list1.get(6)[i+1])) {
                    finance.setOperatingProfit(new Double(list1.get(6)[i+1]));
                }
                if (isNumeric(list1.get(7)[i+1])) {
                    finance.setInvestmentIncome(new Double(list1.get(7)[i+1]));
                }
                if (isNumeric(list1.get(8)[i+1])) {
                    finance.setNetNonOperatingIncomeAndExpenditure(new Double(list1.get(8)[i+1]));
                }
                if (isNumeric(list1.get(9)[i+1])) {
                    finance.setTotalProfit(new Double(list1.get(9)[i+1]));
                }
                if (isNumeric(list1.get(10)[i+1])) {
                    finance.setNetProfit(new Double(list1.get(10)[i+1]));
                }
                if (isNumeric(list1.get(11)[i+1])) {
                    finance.setNetProfitAfterDeductingNonRecurringProfitAndLoss(new Double(list1.get(11)[i+1]));
                }
                if (isNumeric(list1.get(12)[i+1])) {
                    finance.setNetCashFlowFromOperatingActivities(new Double(list1.get(12)[i+1]));
                }
                if (isNumeric(list1.get(13)[i+1])) {
                    finance.setNetIncreaseInCashAndCashEquivalents(new Double(list1.get(13)[i+1]));
                }
                if (isNumeric(list1.get(14)[i+1])) {
                    finance.setTotalAssets(new Double(list1.get(14)[i+1]));
                }
                if (isNumeric(list1.get(15)[i+1])) {
                    finance.setCurrentAssets(new Double(list1.get(15)[i+1]));
                }
                if (isNumeric(list1.get(16)[i+1])) {
                    finance.setTotalLiabilities(new Double(list1.get(16)[i+1]));
                }
                if (isNumeric(list1.get(17)[i+1])) {
                    finance.setCurrentLiabilities(new Double(list1.get(17)[i+1]));
                }
                if (isNumeric(list1.get(18)[i+1])) {
                    finance.setShareholderEquityExcludingMinorityShareholderEquity(new Double(list1.get(18)[i+1]));
                }
                if (isNumeric(list1.get(19)[i+1])) {
                    finance.setWeightedReturnOnEquity(new Double(list1.get(19)[i+1]));
                }
                finances.add(finance);

            }

            return finances;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            inputStream.close();
        }

        return null;
    }
    public  List<String[]> readCsvFile(InputStream inputStream)
            throws FileNotFoundException, IOException
    {

        List<String[]> list = new ArrayList<String[]>();
        FileReader fileReader = null;
        try
        {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "gbk"));
            String regExp = getRegExp();
            String strLine = "";
            String str = "";
            while ((strLine = bufferedReader.readLine()) != null)
            {
                Pattern pattern = Pattern.compile(regExp);
                Matcher matcher = pattern.matcher(strLine);
                List<String> listTemp = new ArrayList<String>();
                while (matcher.find())
                {
                    str = matcher.group();
                    str = str.trim();
                    if (str.endsWith(","))
                    {
                        str = str.substring(0, str.length() - 1);
                        str = str.trim();
                    }
                    if (str.startsWith("\"") && str.endsWith("\""))
                    {
                        str = str.substring(1, str.length() - 1);
                        if (isExisted("\"\"", str))
                        {
                            str = str.replaceAll("\"\"", "\"");
                        }
                    }
                    if (!"".equals(str))
                    {
                        System.out.print(str + " ");
                        listTemp.add(str);
                    }
                }

                list.add((String[]) listTemp
                        .toArray(new String[listTemp.size()]));
            }
        }
        catch (FileNotFoundException e)
        {
            throw e;
        }
        catch (IOException e)
        {
            throw e;
        }
        finally
        {
            try
            {
                if (fileReader != null)
                {
                    fileReader.close();
                }
            }
            catch (IOException e)
            {
                throw e;
            }
        }
        return list;
    }
    /**
     * 正则表达式。
     *
     * @return 匹配csv文件里最小单位的正则表达式。
     */
    private  String getRegExp()
    {
        StringBuffer strRegExps = new StringBuffer();
        strRegExps.append("\"((");
        strRegExps.append(SPECIAL_CHAR_A);
        strRegExps.append("*[,\\n 　])*(");
        strRegExps.append(SPECIAL_CHAR_A);
        strRegExps.append("*\"{2})*)*");
        strRegExps.append(SPECIAL_CHAR_A);
        strRegExps.append("*\"[ 　]*,[ 　]*");
        strRegExps.append("|");
        strRegExps.append(SPECIAL_CHAR_B);
        strRegExps.append("*[ 　]*,[ 　]*");
        strRegExps.append("|\"((");
        strRegExps.append(SPECIAL_CHAR_A);
        strRegExps.append("*[,\\n 　])*(");
        strRegExps.append(SPECIAL_CHAR_A);
        strRegExps.append("*\"{2})*)*");
        strRegExps.append(SPECIAL_CHAR_A);
        strRegExps.append("*\"[ 　]*");
        strRegExps.append("|");
        strRegExps.append(SPECIAL_CHAR_B);
        strRegExps.append("*[ 　]*");
        return strRegExps.toString();
    }
    /**
     * @param argChar
     * @param argStr
     * @return
     */
    private  boolean isExisted(String argChar, String argStr)
    {

        boolean blnReturnValue = false;
        if ((argStr.indexOf(argChar) >= 0)
                && (argStr.indexOf(argChar) <= argStr.length()))
        {
            blnReturnValue = true;
        }
        return blnReturnValue;
    }
    public boolean isNumeric(String content){
        String pattern = "^[\\+\\-]?[\\d]+(\\.[\\d]+)?$";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(content);

        return m.matches();
    }

    private  final String SPECIAL_CHAR_A = "[^\",\\n 　]";

    private  final String SPECIAL_CHAR_B = "[^\",\\n]";

}
